"""
    2.1、获取到check_db这个字段的数据，通过actual_data获取到sql
    2.2、替换掉sql里面的手机号
    2.3、执行sql，获取sql执行结果
    2.4、用这个sql执行结果替换掉actual_data结果的value
    2.5、比对actual_data和expected_data的val
check_db_1={"actual_data":"select * from member where member_phone = #mobile_phone#;",
         "expected_data":"1"}
check_db_2={"actual_data":1,
         "expected_data":"1"}
"""

import ast

from tools.handle_db import mysql
from tools.handle_loging import my_logger
from tools.handle_replace import HandleReplace


class CheckDb:

    def __init__(self):
        self.handle_replace = HandleReplace()

    def __get_db_result(self, sql):
        result = mysql.get_db_all_data(sql)
        return result


    def setup_sql(self,sql_list):
        """
        执行前置sql语句
        :param sql_list:
                :type=list
                 需要执行的sql语句
        :return:无
        """
        if sql_list:
            if isinstance(sql_list,list):
                sql_list = sql_list
            else:
                sql_list = ast.literal_eval(sql_list)
            for sql in sql_list:
                mysql.get_db_all_data(sql=sql)
        else:
            my_logger.info(msg="sql_list为空，不需要执行前置sql语句")

    def check_db_new(self,check_db):
        if check_db:
            if isinstance(check_db,dict):
                check_db = check_db
            else:
                check_db = ast.literal_eval(check_db)
            #check_db 数据替换之后的数据
            # {"actual_data":["db","select * from member where mobile_phone = #mobile_phone#;","expected_data":"1"]}
            # {"actual_data":"1","expected_data":"1"]}
            new_check_db = self.handle_replace.replace_check_db_data(check_db=check_db)
            my_logger.info(msg="数据库校验期望结果\n{}".format(new_check_db["expected_data"]))
            my_logger.info(msg="数据库校验实际结果\n{}".format(new_check_db["actual_data"]))
            assert new_check_db["expected_data"] == new_check_db["actual_data"]
        else:
            my_logger.info(msg='check_db数据为空，说明不需要进行数据库校验')


    def check_db(self, check_db):
        try:
            if check_db:
                check_db = ast.literal_eval(check_db)
                actual_data_sql = check_db["actual_data"]  # 获取实际结果查询sql
                result = self.__get_db_result(sql=actual_data_sql)  # 获取数据库查询结果
                check_db["actual_data"] = str(len(result))  # 这里要注意数据类型
                my_logger.info(msg="数据库断言预期结果:\n{}".format(check_db["expected_data"]))
                my_logger.info(msg="数据库断言实际结果:\n{}".format(check_db["actual_data"]))
                if check_db["actual_data"] == check_db["expected_data"]: # 实际结果与预期结果进行比对
                    my_logger.info(msg='数据库断言成功')
                else:
                    my_logger.info(msg='数据库断言失败')
                    raise AssertionError
            else:
                my_logger.info(msg='无需做数据库断言')
        except Exception as e:
            my_logger.exception(e)
            raise AssertionError


    def check_db_many_start_request(self,check_db_many):
        """
    {"first": ["db", "select leave_amount from member where mobile_phone='18820992515'"],
    "first": ["db", "select leave_amount from member where mobile_phone='18820992515'"]
    "expected_data": "first+1000",
    "actual_data": ["db", "select leave_amount from member where mobile_phone='18820992515'"]
    }
            { "first": ["db", "select leave_amount from member where mobile_phone='18820992515'"],
            "second": ["db", "select leave_amount from member where mobile_phone='18820992515'"]}
        :param check_db_many:
        :return:

            {"first": 100,
            "second": 200,
            "expected_data": "first+second+1000",
            "actual_data": ["db", "select leave_amount from member where mobile_phone='18820992515'"]
    }
        """
        if check_db_many:
            if isinstance(check_db_many,dict):
                check_db_many = check_db_many
            else:
                check_db_many = ast.literal_eval(check_db_many)

            replace_dict ={}
            for key in check_db_many.keys():
                if key != "expected_data" and key != "actual_data":
                    # 执行sql语句，拿到数据库查询的数据
                    replace_dict[key] = check_db_many[key]

            # 把需要替换的参数，拿去替换，1、先执行sql,2、再替换value,返回替换后的结果
            new_check_db_many = self.handle_replace.replace_check_db_data(check_db=replace_dict)

            check_db_many.update(new_check_db_many) #字典更新，key存在就替换，key不存在就新增
            return check_db_many
        else:
            return check_db_many

    def __handle_check_db_many_expected_data(self,check_db_many,expected_data):
        # expected_rule = "first+1000"
        # 替换之后 expected_rule =   (100 + 10000)
        expected_rule =expected_data["expected_data"]
        for key  in  check_db_many.keys():
            if key in expected_rule:
                expected_rule = expected_rule.replace(key,str(check_db_many[key]))
        # 计算期望结果的值expected_data
        expected_data_value = eval(expected_rule)
        expected_data["expected_data"] = expected_data_value
        # 返回：{"expected_data":"10000"}
        return expected_data

    def check_db_many_end_request(self,check_db_many):
        """
        {"first": 100,
            "expected_data": "first+1000",
            "actual_data": ["db", "select leave_amount from member where mobile_phone='#mobile_phone#'"]
    }   check_db_many:
            :type=dict,str
        :return:
        """
        if check_db_many:
            if isinstance(check_db_many,dict):
                check_db_many = check_db_many
            else:
                check_db_many = ast.literal_eval(check_db_many)
            # 实际结果
            actual_data = {"actual_data":check_db_many["actual_data"]}
            # 替换后的实际结果
            new_actual_data = self.handle_replace.replace_check_db_data(check_db=actual_data)

            # 期望结果
            expected_data = {"expected_data":check_db_many["expected_data"]}
            # 按规则计算期望结果的值，并替换
            new_expected_data=self.__handle_check_db_many_expected_data(check_db_many=check_db_many,expected_data=expected_data)

            assert str(new_expected_data["expected_data"]) == str(new_actual_data["actual_data"])
            # 实际结果与期望结果进行对比
        else:
            my_logger.info(msg="不需要断言接口请求前后的数据库数据")






